# 单例模式1:调用的时候需要一个单例已存在。所有写在__call__里面
# 类的方式写一个单例
# 类的方式 自定义元类 方法执行顺序：
# python自上而下的，先执行SingleMetaClass.__init__
# 然后到入口函数这里 p1 = SinglePerson() 实例化类对象 执行__cal__函数，进行初始化单例
# 外部可以调用的私有方法是单下划线开始的私有属性。 _instance
class SingleMetaClass(type):

    def __init__(cls, *args, **kwargs):
        cls._instance = None
        super().__init__(*args, **kwargs)
    def __call__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__call__(*args, **kwargs)
        return cls._instance

class SinglePerson(object, metaclass=SingleMetaClass):
    pass

if __name__ == '__main__':
    p1 = SinglePerson() # 执行这步时执行__cal__函数，进行初始化单例
    # p1 实例化的时候，先调用 __new__ 私有函数
    p2 = SinglePerson()

    # is 比较的是内存中是不是一个对象，内存地址是否一样
    print(p1 is p2)  # True
    #
    print(p1, p2)
    # <__main__.SinglePerson object at 0x0000016EC64D58E0>
    # <__main__.SinglePerson object at 0x0000016EC64D58E0>
